home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
msysjour
/
vol07
/
02
/
controls
/
init.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-29
|
10KB
|
365 lines
/*
* INIT.C
*
* LibMain entry point and initialization code for the MicroScroll
* custom control DLL that is likely to be used once or very
* infrequently.
*
* Version 1.1, October 1991, Kraig Brockschmidt
*/
#include <windows.h>
#include "muscrdll.h"
HANDLE hgInst; //Need this for dialog editor style box.
/*
* LibMain
*
* Purpose:
* DLL-specific entry point called from LibEntry. Initializes
* the DLL's heap and registers the MicroScroll custom control
* class.
*
* Parameters:
* hInstance HANDLE instance of the DLL.
* wDataSeg WORD segment selector of the DLL's data segment.
* wHeapSize WORD byte count of the heap.
* lpCmdLine LPSTR to command line used to start the module.
*
* Return Value:
* HANDLE Instance handle of the DLL.
*
*/
HANDLE FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg,
WORD cbHeapSize, LPSTR lpCmdLine)
{
//Go register the control
if (FRegisterControl(hInstance))
{
hgInst=hInstance;
if (0!=cbHeapSize)
UnlockData(0);
return hInstance;
}
hgInst=NULL;
return (HANDLE)NULL;
}
/*
* FRegisterControl
*
* Purpose:
* Registers the MicroScroll control class, including CS_GLOBALCLASS
* to make the control available to all applications in the system.
*
* Parameters:
* hInstance HANDLE Instance of the application or DLL that will
* own this class.
*
* Return Value:
* BOOL TRUE if the class is registered, FALSE otherwise.
* TRUE is also returned if the class was already
* registered.
*/
BOOL PASCAL FRegisterControl(HANDLE hInstance)
{
static BOOL fRegistered=FALSE;
WNDCLASS wc;
char szClass[40];
if (!fRegistered)
{
//Load the class name
if (0==LoadString(hInstance, IDS_CLASSNAME, szClass, 40))
return FALSE;
wc.lpfnWndProc = MicroScrollWndProc;
wc.cbClsExtra = CBCLASSEXTRA;
wc.cbWndExtra = CBWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = COLOR_BTNFACE+1;
wc.lpszMenuName = NULL;
wc.lpszClassName = szClass;
wc.style = CS_DBLCLKS | CS_GLOBALCLASS |
CS_VREDRAW | CS_HREDRAW;
fRegistered=RegisterClass(&wc);
}
return fRegistered;
}
/*
* LMicroScrollCreate
*
* Purpose:
* Handles both WM_NCCREATE and WM_CREATE messages:
* WM_NCCREATE: Allocate control MUSCROLL structure. Any sort
* of initialization that should force the create
* to fail should be included in this case.
*
* WM_CREATE: Fill the MUSCROLL structure; parse the text
* for initial min, max, and position for the
* MSS_TEXTHASRANGE style; clear all states;
* set the expansion handle to NULL.
*
* Parameters:
* hWnd HWND handle to the control window.
* iMsg WORD message, either WM_NCCREATE or WM_CREATE.
* pMS PMUSCROLL pointer to existing MUSCROLL structure.
*
* Return Value:
* LONG 0L if memory could not be allocated on WM_NCCREATE.
* 1L in all other cases.
*/
LONG PASCAL LMicroScrollCreate(HWND hWnd, WORD iMsg, PMUSCROLL pMS,
LPCREATESTRUCT lpCreate)
{
HANDLE hMem;
BOOL fTextRange;
WORD iMin, iMax, iPos;
if (WM_NCCREATE==iMsg)
{
/*
* Allocate extra FIXED memory for the control's MUSCROLL
* structure and store that handle in the minimal window
* extra bytes allocated for the control.
*
* Note that LPTR includes LMEM_ZEROINIT, so all fields are
* initially zero.
*/
hMem=LocalAlloc(LPTR, CBMUSCROLL);
if (NULL==hMem)
return 0L;
SetWindowWord(hWnd, GWW_MUSCROLLHMEM, (HANDLE)hMem);
}
if (WM_CREATE==iMsg)
{
//Our associate is the parent by default.
pMS->hWndAssociate=(HWND)GetWindowWord(hWnd, GWW_HWNDPARENT);
//Copy styles
pMS->dwStyle =lpCreate->style;
/*
* Enforce exclusive MSS_VERTICAL and MSS_HORIZONTAL,
* defaulting to MSS_VERTICAL.
*/
if ((MSS_VERTICAL & pMS->dwStyle) && (MSS_HORIZONTAL & pMS->dwStyle))
pMS->dwStyle &= ~MSS_HORIZONTAL;
//Either parse the text or use defaults for initial range.
fTextRange=FALSE;
if (MSS_TEXTHASRANGE & pMS->dwStyle)
{
fTextRange=FTextParse((LPSTR)lpCreate->lpszName,
&iMin, &iMax, &iPos);
/*
* Verify that the position is in the given range. If
* the position is outside the range, force it to the
* middle.
*/
if (fTextRange)
{
if (iPos < iMin || iPos > iMax)
iPos=(iMin + iMax) >> 1;
}
}
/*
* Use defaults if we never had MSS_TEXTHASRANGE or
* FTextParse failed.
*/
pMS->iMin=(fTextRange ? iMin : IDEFAULTMIN);
pMS->iMax=(fTextRange ? iMax : IDEFAULTMAX);
pMS->iPos=(fTextRange ? iPos : IDEFAULTPOS);
//Clear out all initial states.
StateClear(pMS, MUSTATE_ALL);
//Indicate that all colors are defaults.
for (iMin=0; iMin < CCOLORS; iMin++)
pMS->rgCr[iMin]=(COLORREF)-1L;
}
return 1L;
}
/*
* FTextParse
*
* Purpose:
* Parses window text for a valid range and initial position.
* This function is used when creating the control or setting the
* window text to set the initial range and position but is also
* used to validate text entered in the Style dialog in the Dialog
* Editor interface if the MSM_TEXTHASRANGE style is selected.
*
* The range and position must all be valid for any change to
* occur in piMin, piMax, and piPos.
*
* Parameters:
* psz LPSTR pointer to the window text to parse out
* the range and the position.
* piMin LPINT pointer to location to store minimum.
* piMax LPINT pointer to location to store maximum.
* piPos LPINT pointer to location to store position.
*
* Return Value:
* BOOL TRUE if the function successfully initializes
* the range and position. FALSE if any part of
* the text is not a valid number between comma
* delimeters.
*/
BOOL PASCAL FTextParse(LPSTR psz, LPINT piMin, LPINT piMax, LPINT piPos)
{
int iMin;
int iMax;
int iCur;
if (psz==NULL)
return FALSE;
/*
* Parse off the bottom of the range. Note that we depend
* on WTranslateUpToChar to modify psz to point to the character
* after the delimeter which is why we pass &psz.
*/
iMin=WTranslateUpToChar(&psz, ',');
//Check for valid value AND that there's text remaining.
if (-1==iMin || 0==*psz)
return FALSE;
//Parse off the top of the range.
iMax=WTranslateUpToChar(&psz, ',');
//Check for valid value AND that there's text remaining.
if (-1==iMax || 0==*psz)
return FALSE;
//Parse off the position and validate it.
iCur=WTranslateUpToChar(&psz, ',');
if (-1==iCur)
return FALSE;
//Store the parsed values in the return locations.
*piMin=iMin;
*piMax=iMax;
*piPos=iCur;
return TRUE;
}
/*
* WTranslateUpToChar
*
* Purpose:
* Scans a string for digits, converting the series of digits to
* an integer value as the digits are scanned. Scanning stops
* at chDelimeter or the end of the string.
*
* If the scan sees a non-digit character, -1 is returned to indicate
* error. If the scan sees a null-terminator before any text, we
* return 0.
*
* Parameters:
* ppsz LPSTR * pointer to pointer to the string to scan.
* On return, the pointer will point to the character
* after the delimeter OR the NULL terminator.
*
* We want a pointer to the pointer so we can modify
* that pointer for the calling function since we are
* using the return value for the parsed value
*
* chDelimiter char delimeter at which the scanning stops.
*
* Return Value:
* WORD -1 if the string contains non-digits excluding
* the comma. Otherwise the converted value is
* returned and the pointer to the address after
* the comma is stored at ppsz.
*/
WORD PASCAL WTranslateUpToChar(LPSTR FAR *ppsz, char chDelimeter)
{
WORD wRet=0;
char ch;
LPSTR psz;
psz=*ppsz;
//Fail if there's no more string to parse.
if (0==*psz)
return -1;
//Scan string, stopping at 0 or chDelimeter
while (ch=*psz)
{
if (ch==chDelimeter)
{
psz++; //Skip delimeter
break;
}
//Check for digits, returning -1 on a non-digit.
ch-='0';
if (ch < 0 || ch > 9)
return -1;
//Add up the value as we scan.
wRet=(wRet*10) + (WORD)ch;
/*
* We increment psz here so if we hit a null-terminator
* psz is always valid. If we incremented in the while
* statement then psz might be past the null-terminator
* and possibly invalid.
*/
psz++;
}
/*
* Store the new pointer and the value. Note that the *psz++
* already incremented psz past the delimeter AND the zero.
*/
*ppsz=psz;
return wRet;
}